#**************************************************************************
#*********************---------------------------------**********************
#********************|    Copyright (c) 2003 - 2022    |*********************
#********************|      by VIRE Technologies.        |*********************
#********************|       All Rights Reserved           |*********************
#*********************---------------------------------**********************
#**************************************************************************
#
# If any question, please write to VIRE Technologies for
# more information:
#			Techart Plaza, A16, No.30 XueYuan Road,
#			Haidian District Beijing 100083,
#			P.R. China
#
# For more, please visit company website: www.vire.cn
#**************************************************************************

# *****************************************************************************
# CMAKE file: vis_plugins
# Macros and configuration to support builds and installation of visualization
# software that hosts plugins: e.g., wkf, warlock, results vis, EWX.IDE
# *****************************************************************************
include(ewxdev_project)

# Recursively find all plugin configuration files
set(PLUGIN_CONFIG_FILES)
foreach(PLUGIN_ROOT_DIR ${PLUGIN_ROOT_DIRS})
   file(GLOB_RECURSE PLUGIN_CONFIGS ${PLUGIN_ROOT_DIR}/*_plugin.cmake)
   set(PLUGIN_CONFIG_FILES ${PLUGIN_CONFIG_FILES} ${PLUGIN_CONFIGS})
endforeach()

# Adds the plugin as a CMake option (BUILD_<HOSTNAME>_PLUGIN_xxxx) and
# sets directory properties that locate and identify the plugins
function(add_vis_plugin_project HOSTNAME PROJSOURCE PROJNAME PROJBUILD)
   set(BUILD_${HOSTNAME}_PLUGIN_${PROJNAME} ${PROJBUILD} CACHE BOOL "Build ${HOSTNAME} with Plugin ${PROJNAME}")
   set_property(DIRECTORY PROPERTY ${HOSTNAME}_PLUGIN_PROJECT_NAMES ${PROJNAME} APPEND)
   set_property(DIRECTORY PROPERTY ${HOSTNAME}_PLUGIN_PROJECT_SRCS "${PROJSOURCE}" APPEND)
endfunction()

# Add any plugins that have been found to the build
macro(configure_vis_plugin HOSTNAME PLUGIN_CONFIG_FILE)
   # Initialize variables to be set by plugin configuration
   set(${HOSTNAME}_PLUGIN_NAME) # The plugin name
   set(${HOSTNAME}_PLUGIN_SOURCE_PATH) # Relative path from plugin's cmake to source directory
   set(${HOSTNAME}_PLUGIN_BUILD ${ARGV2}) # Build plugin by default

   include("${PLUGIN_CONFIG_FILE}")
   if (${HOSTNAME}_PLUGIN_NAME)
      message(STATUS "Configuring ${HOSTNAME} Plugin ${${HOSTNAME}_PLUGIN_NAME}")
      get_filename_component(PLUGIN_CONFIG_DIR "${PLUGIN_CONFIG_FILE}" PATH)
      set(PROJSOURCE "${PLUGIN_CONFIG_DIR}/${${HOSTNAME}_PLUGIN_SOURCE_PATH}")
      add_vis_plugin_project(${HOSTNAME} "${PROJSOURCE}" ${${HOSTNAME}_PLUGIN_NAME} ${${HOSTNAME}_PLUGIN_BUILD})
   endif()
endmacro()

ewxdev_absolute_paths(PLUGIN_CONFIG_FILES ${PLUGIN_CONFIG_FILES})

# Configure the build to include plugins
macro(use_vis_plugins HOSTNAME)
   SET(options)
   SET(oneValueArgs)
   SET(multiValueArgs BESIDES)
    
   cmake_parse_arguments(_ARGS 
            "${options}" 
            "${oneValueArgs}" 
            "${multiValueArgs}" 
            ${ARGN})
        
            
   foreach(PLUGIN_CONFIG_FILE ${PLUGIN_CONFIG_FILES})
      #
      SET(USE_PLUGIN ON)
      IF(_ARGS_BESIDES)
         get_filename_component(_t_PLUGIN_CONFIG_DIR "${PLUGIN_CONFIG_FILE}" PATH)
         get_filename_component(__t_Plugin_name "${_t_PLUGIN_CONFIG_DIR}" NAME)
         list(FIND _ARGS_BESIDES ${__t_Plugin_name} _index)
         if(NOT ${_index} EQUAL -1)
            SET(USE_PLUGIN OFF)
            message(STATUS "##====${HOSTNAME} Default No Use Plugin: ${__t_Plugin_name}")
         endif()
      ENDIF()
      configure_vis_plugin(${HOSTNAME} ${PLUGIN_CONFIG_FILE} ${USE_PLUGIN})
   endforeach()

   get_property(${HOSTNAME}_PLUGIN_PROJECT_NAMES DIRECTORY PROPERTY ${HOSTNAME}_PLUGIN_PROJECT_NAMES)
   get_property(${HOSTNAME}_PLUGIN_PROJECT_SRCS DIRECTORY PROPERTY ${HOSTNAME}_PLUGIN_PROJECT_SRCS)
 
   foreach(PROJNAME ${${HOSTNAME}_PLUGIN_PROJECT_NAMES})
      if(BUILD_${HOSTNAME}_PLUGIN_${PROJNAME})
         list(FIND ${HOSTNAME}_PLUGIN_PROJECT_NAMES ${PROJNAME} IDX)
         list(GET ${HOSTNAME}_PLUGIN_PROJECT_SRCS ${IDX} PROJSOURCE)
         add_subdirectory("${PROJSOURCE}" "${PROJNAME}")
      endif()
   endforeach()
endmacro()

macro(ewxdev_package_include_directories TARGET)
   foreach(arg ${ARGN})
      foreach(pkg ${arg})
         string(REGEX MATCH "([^-]*).*" pkgNameMatch "${pkg}")
         if(NOT pkgNameMatch)
            message(FATAL_ERROR "Third party package: ${pkg} cannot determine package name")
         endif()
         set(pkgBaseName ${CMAKE_MATCH_1})
         message("pkgBaseName ${pkgBaseName} ${pkgBaseName}_INCLUDE_DIR=${${pkgBaseName}_INCLUDE_DIR}")
         if (DEFINED ${pkgBaseName}_INCLUDE_DIR)
            #target_include_directories(${TARGET} PRIVATE )
            target_include_directories(${TARGET} 
               PRIVATE
                  "$<BUILD_INTERFACE:${${pkgBaseName}_INCLUDE_DIR}>"
            )

         endif()
      endforeach()
   endforeach()
endmacro()

# Move plugin into subdirectory
# Required in order to run in debug from Visual Studio
macro(vis_plugin_post_build_base PLUGIN_NAME PLUGIN_DIR)
   if (WIN32)
      add_custom_command(TARGET ${PLUGIN_NAME} POST_BUILD
                         COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${PLUGIN_NAME}>/${PLUGIN_DIR}" VERBATIM
                         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${PLUGIN_NAME}> $<TARGET_FILE_DIR:${PLUGIN_NAME}>/${PLUGIN_DIR} VERBATIM)
   endif()
endmacro()

macro(vis_plugin_post_build PLUGIN_NAME)
   if (WIN32)
      get_filename_component(DIR_NAME ${PLUGIN_INSTALL_DIR} NAME)
      vis_plugin_post_build_base(${PLUGIN_NAME} ${DIR_NAME})
      #add_custom_command(TARGET ${PLUGIN_NAME} POST_BUILD
                        # COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${PLUGIN_NAME}>/${DIR_NAME}" VERBATIM
                         #COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${PLUGIN_NAME}> $<TARGET_FILE_DIR:${PLUGIN_NAME}>/${DIR_NAME} VERBATIM)
   endif()
endmacro()

# Optional arguments:
# NO_INSTALL_SOURCE
#     Specifies that the install commands should not be ran on the source

macro(vis_plugin_install_base PLUGIN_NAME TARGET_DIR PLUGIN_DIR)
   set(options NO_INSTALL_SOURCE)
   cmake_parse_arguments(_PI "${options}" "" "" ${ARGN})

   install(TARGETS ${PLUGIN_NAME} RUNTIME DESTINATION bin/${PLUGIN_DIR} COMPONENT Runtime
                                  LIBRARY DESTINATION bin/${PLUGIN_DIR} COMPONENT Library)
   # Install PDB file for Debug configuration when using MSVC
   if (MSVC)
      install(FILES $<TARGET_PDB_FILE:${PLUGIN_NAME}> DESTINATION bin/${PLUGIN_DIR}
              CONFIGURATIONS Debug RelWithDebInfo COMPONENT Runtime)
   endif() 
   if (WSF_INSTALL_SOURCE AND NOT _PI_NO_INSTALL_SOURCE)
      install_sources_all_files(../ ${TARGET_DIR})
   endif()
endmacro()

macro(vis_plugin_install PLUGIN_NAME TARGET_DIR)
   set(options NO_INSTALL_SOURCE)
   cmake_parse_arguments(_PI "${options}" "" "" ${ARGN})

   install(TARGETS ${PLUGIN_NAME} RUNTIME DESTINATION ${PLUGIN_INSTALL_DIR} COMPONENT Runtime
                                  LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR} COMPONENT Library)
   # Install PDB file for Debug configuration when using MSVC
   if (MSVC)
      install(FILES $<TARGET_PDB_FILE:${PLUGIN_NAME}> DESTINATION ${PLUGIN_INSTALL_DIR}
              CONFIGURATIONS Debug RelWithDebInfo COMPONENT Runtime)
   endif() 
   if (WSF_INSTALL_SOURCE AND NOT _PI_NO_INSTALL_SOURCE)
      install_sources_all_files(../ ${TARGET_DIR})
   endif()
endmacro()

# plugin_cmakelists_template(PLUGIN_NAME
#                            HOST_TARGET
#                            [THIRD_PARTY_INCLUDE_DIRS <pkgs>...]
#                            [THIRD_PARTY_LINK_LIBS <pkgs>...]
#                            [QT_MODULES <modules>...]
#                            [LIBRARIES <libs>...]
#                            [SOURCE_INSTALL_DIR <directory>]
#                            [NO_INSTALL_SOURCE])
# Optional arguments:
# THIRD_PARTY_INCLUDE_DIRS
#     Specifies 3rd party packages to add to include directories
# THIRD_PARTY_LINK_LIBS
#     Specifies 3rd party package libraries to link target with
# QT_MODULES
#     Specifies additional Qt modules (beyond Core, Gui, Widgets) to import as targets
# LIBRARIES
#     Specifies library targets to link to
# SOURCE_INSTALL_DIR
#     Specifies the non-standard relative source target install dir
# NO_INSTALL_SOURCE
#     Specifies that the install commands should not be ran
macro(plugin_cmakelists_template PLUGIN_NAME HOST_TARGET)
   # Parse optional arguments to macro
   set(options NO_INSTALL_SOURCE)
   set(oneValueArgs SOURCE_INSTALL_DIR)
   set(multiValueArgs THIRD_PARTY_INCLUDE_DIRS THIRD_PARTY_LINK_LIBS QT_MODULES LIBRARIES)
   cmake_parse_arguments(PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

   # *****************************************************************************
   # Get the source files
   file(GLOB SRCS *.cpp *.hpp *.h)
   file(GLOB QRC ${CMAKE_CURRENT_SOURCE_DIR}/../ui/resources/*.qrc)
   file(GLOB UIS ${CMAKE_CURRENT_SOURCE_DIR}/../ui/*.ui)

   include(qt_project)
   configure_qt_project(MODULES ${PLUGIN_QT_MODULES} UI UI_HEADERS ${UIS})

   # *****************************************************************************
   # The library we are trying to build
   include_directories(${CMAKE_BINARY_DIR}/include)
   add_library(${PLUGIN_NAME} ${SRCS} ${QRC} ${UI_HEADERS})

   # Place under plugins folder in IDE
   set_property(TARGET ${PLUGIN_NAME} PROPERTY 
      FOLDER "${HOST_TARGET}/plugins")

   vis_plugin_post_build(${PLUGIN_NAME})

   set(_SOURCE_INSTALL)
   if (PLUGIN_NO_INSTALL_SOURCE)
         set(_SOURCE_INSTALL "NO_INSTALL_SOURCE")
   endif()
   if (PLUGIN_SOURCE_INSTALL_DIR)
      set(REL_PATH ${PLUGIN_SOURCE_INSTALL_DIR})
   else()
      file(RELATIVE_PATH REL_PATH ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/..)
   endif()
   vis_plugin_install(${PLUGIN_NAME} ${REL_PATH} ${_SOURCE_INSTALL})

   # *****************************************************************************
   # Add project to Sphinx for documentation
   add_wsf_doc_input(${CMAKE_CURRENT_SOURCE_DIR}/..)

   # Add source directories to doxygen input
   IF(EWX_INSTALL_PLUGINS_DOXYGEN)
      add_wsf_doxygen_input(${CMAKE_CURRENT_SOURCE_DIR})
   ENDIF()

   if (PLUGIN_THIRD_PARTY_INCLUDE_DIRS)
      foreach(pkg ${PLUGIN_THIRD_PARTY_INCLUDE_DIRS})
         #ewxdev_package_include_directories(${PLUGIN_NAME} ${pkg})
      endforeach()
   endif()

   if (PLUGIN_THIRD_PARTY_LINK_LIBS)
      foreach(pkg ${PLUGIN_THIRD_PARTY_LINK_LIBS})
         #ewxdev_package_link_libraries(${PLUGIN_NAME} ${pkg})
         ewx_3rd_package_link_libraries_target(${PLUGIN_NAME} ${pkg})
      endforeach()
   endif()

   if (PLUGIN_LIBRARIES)
      foreach(lib ${PLUGIN_LIBRARIES})
         if(NOT EWX_USE_SDK_MODE)
            target_link_libraries(${PLUGIN_NAME} ${lib})
         ELSE()
            if(TARGET ${lib})
               target_link_libraries(${PLUGIN_NAME} ${lib})
            else()
               target_link_libraries(${PLUGIN_NAME} EWX::${lib})
            endif()
         ENDIF()
      endforeach()
   endif()

   if (PLUGIN_QT_MODULES)
      foreach(module ${PLUGIN_QT_MODULES})
         target_link_libraries(${PLUGIN_NAME} Qt5::${module})
         install_qt_lib(Qt5${module})
      endforeach()
   endif()
endmacro()

#add by luli:20221205
#主要增加处理插件多目录生成&安装,以支撑同一插件对不同的应用的支撑
#暂时不动原有的目录
macro(ewx_plugin_cmakelists_template PLUGIN_NAME HOST_TARGET)
   # Parse optional arguments to macro
   set(options NO_INSTALL_SOURCE)
   set(oneValueArgs SOURCE_INSTALL_DIR)
   set(multiValueArgs 
      THIRD_PARTY_INCLUDE_DIRS 
      THIRD_PARTY_LINK_LIBS 
      QT_MODULES 
      LIBRARIES
      PLUGIN_DIRS 
      ADD_SOURCE_DIRS
      )
   cmake_parse_arguments(PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

   # *****************************************************************************
   # Get the source files
   file(GLOB SRCS *.cpp *.hpp)
   file(GLOB QRC ${CMAKE_CURRENT_SOURCE_DIR}/../ui/resources/*.qrc)
   file(GLOB UIS ${CMAKE_CURRENT_SOURCE_DIR}/../ui/*.ui)

   IF(PLUGIN_ADD_SOURCE_DIRS)
      file(GLOB SRCS *.cpp *.hpp)
      foreach(dir ${PLUGIN_ADD_SOURCE_DIRS})
         file(GLOB add_source_SRCS ${dir}/*.cpp ${dir}/*.hpp)
         SET(SRCS ${SRCS} ${add_source_SRCS})
      endforeach()
   ENDIF()

   include(qt_project)
   configure_qt_project(MODULES ${PLUGIN_QT_MODULES} UI UI_HEADERS ${UIS})

   # *****************************************************************************
   # The library we are trying to build
   include_directories(${CMAKE_BINARY_DIR}/include)
   add_library(${PLUGIN_NAME} ${SRCS} ${QRC} ${UI_HEADERS})

   # Place under plugins folder in IDE
   set_property(TARGET ${PLUGIN_NAME} PROPERTY 
      FOLDER "${HOST_TARGET}/plugins")
   IF(NOT PLUGIN_PLUGIN_DIRS)
      vis_plugin_post_build(${PLUGIN_NAME})
   ELSE()
      foreach(dir ${PLUGIN_PLUGIN_DIRS})
         vis_plugin_post_build_base(${PLUGIN_NAME} ${dir})
      endforeach()
   ENDIF()

   set(_SOURCE_INSTALL)
   if (PLUGIN_NO_INSTALL_SOURCE)
         set(_SOURCE_INSTALL "NO_INSTALL_SOURCE")
   endif()
   if (PLUGIN_SOURCE_INSTALL_DIR)
      set(REL_PATH ${PLUGIN_SOURCE_INSTALL_DIR})
   else()
      file(RELATIVE_PATH REL_PATH ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/..)
   endif()
   IF(NOT PLUGIN_PLUGIN_DIRS)
      vis_plugin_install(${PLUGIN_NAME} ${REL_PATH} ${_SOURCE_INSTALL})
   ELSE()
      foreach(dir ${PLUGIN_PLUGIN_DIRS})
         vis_plugin_install_base(${PLUGIN_NAME} ${REL_PATH} ${dir} ${_SOURCE_INSTALL})
      endforeach()
   ENDIF()
   

   # *****************************************************************************
   # Add project to Sphinx for documentation
   add_wsf_doc_input(${CMAKE_CURRENT_SOURCE_DIR}/..)

   # Add source directories to doxygen input
   IF(EWX_INSTALL_PLUGINS_DOXYGEN)
      add_wsf_doxygen_input(${CMAKE_CURRENT_SOURCE_DIR})
   ENDIF()

   if (PLUGIN_THIRD_PARTY_INCLUDE_DIRS)
      foreach(pkg ${PLUGIN_THIRD_PARTY_INCLUDE_DIRS})
         ewxdev_package_include_directories(${PLUGIN_NAME} ${pkg})
      endforeach()
   endif()

   if (PLUGIN_THIRD_PARTY_LINK_LIBS)
      foreach(pkg ${PLUGIN_THIRD_PARTY_LINK_LIBS})
         ewxdev_package_link_libraries(${PLUGIN_NAME} ${pkg})
      endforeach()
   endif()

   if (PLUGIN_LIBRARIES)
      foreach(lib ${PLUGIN_LIBRARIES})
         target_link_libraries(${PLUGIN_NAME} ${lib})
      endforeach()
   endif()

   if (PLUGIN_QT_MODULES)
      foreach(module ${PLUGIN_QT_MODULES})
         target_link_libraries(${PLUGIN_NAME} Qt5::${module})
         install_qt_lib(Qt5${module})
      endforeach()
   endif()
endmacro()
